package fr.babos.test.touch 
{
	import com.greensock.easing.Back;
	import com.greensock.easing.Strong;
	import com.greensock.plugins.ScrollRectPlugin;
	import com.greensock.plugins.TweenPlugin;
	import com.greensock.TweenMax;
	import flash.display.Bitmap;
	import flash.display.BlendMode;
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.TouchEvent;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.text.StageText;
	import flash.ui.Multitouch;
	import flash.ui.MultitouchInputMode;
	import fr.babos.touch.delegate.IGestureTouchDelegate;
	import fr.babos.touch.emulator.GestureTouchEmulator;
	import fr.babos.touch.emulator.MouseToTouchEmulator;
	import fr.babos.touch.events.GestureTouchDragEvent;
	import fr.babos.touch.events.GestureTouchEvent;
	import fr.babos.touch.indicator.TouchIndicator;
	import fr.babos.utils.DisplayObjectUtils;
	
	/**
	 * @author ZoulouX
	 */
	public class TouchTest extends Sprite implements IGestureTouchDelegate
	{
		private var container:Sprite;
		private var imageContainer:Sprite;
		private var back:Sprite;
		private var _mask1:Sprite;
		private var _mask2:Sprite;
		private var _antiMask:Sprite;
		private var _images:Array = [];
		[Embed(source="../../../../../lib/graphics/flash.jpg")]
		public static const ImageClass:Class;
		
		protected var _image1:Bitmap;
		
		
		public function TouchTest ()
		{
			if (stage != null)
				init()
			else
				addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		protected function init (event:Event = null):void
		{
			//TweenPlugin.activate([ScrollRectPlugin]);
			
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			stage.frameRate = 60;
			
			//stage.autoOrients = false;
			
			/*
			var b:Sprite = new Sprite();
			
			b.graphics.beginFill(0x0000FF, .2);
			b.graphics.drawRect(0, 0, 1024, 768);
			b.graphics.endFill();
			b.cacheAsBitmap = true;
			b.cacheAsBitmapMatrix = new Matrix();
			addChild(b);
			*/
			
			if (Multitouch.supportsTouchEvents)
			{
				Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
				//TouchIndicator.enableOn(stage);
			}
			else
			{
				MouseToTouchEmulator.emulate(stage, true, true, true);
			}
			
			imageContainer = new Sprite();
			imageContainer.name = "imageContainer";
			
			var m:Matrix = new Matrix();
			m.scale(0.1, 0.1);
			
			for (var i:int = 0; i < 10; i++) 
			{
				_image1 = new ImageClass();
				
				_image1.name = "image" + i;
				
				_image1.scaleX = .1;
				_image1.scaleY = _image1.scaleX;
				
				_image1.x = i * _image1.width;
				_image1.y = 70;
				
				_image1.cacheAsBitmap = true;
				_image1.cacheAsBitmapMatrix = m;
				
				imageContainer.addChild(_image1);
				
				_images.push(_image1);
			}
			
			//imageContainer.opaqueBackground = true;
			
			/*
			imageContainer.graphics.beginFill(0x000000, .5);
			imageContainer.graphics.drawRect(_image1.x - 10, _image1.y - 10, _image1.width + 20, _image1.height + 20);
			imageContainer.graphics.endFill();
			*/
			
			container = new Sprite();
			container.name = "container";
			
			
			const maskWidth:uint = 300;
			
			back = new Sprite();
			back.name = "back";
			
			back.graphics.beginFill(0xFF8888, 1);
			back.graphics.drawRect(0, 0, maskWidth, 400);
			back.graphics.endFill();
			
			back.cacheAsBitmap = true;
			back.cacheAsBitmapMatrix = new Matrix();
			
			/*
			_antiMask = new Sprite();
			
			_antiMask.graphics.beginFill(0xFF0000, 1);
			_antiMask.graphics.drawRect( -50, -50, 1024, 768);
			_antiMask.graphics.drawRect(0, 0, 800, 500);
			_antiMask.graphics.endFill();
			
			_antiMask.mouseEnabled = false;
			_antiMask.cacheAsBitmap = true;
			_antiMask.cacheAsBitmapMatrix = new Matrix();
			*/
			
			_mask1 = new Sprite();
			_mask2 = new Sprite();
			
			_mask1.name = "mask1";
			_mask2.name = "mask2";
			
			_mask1.graphics.beginFill(0x000000, 1);
			_mask1.graphics.drawRect(0, 0, maskWidth, 400);
			_mask1.graphics.endFill();
			_mask1.opaqueBackground = true;
			
			_mask2.graphics.beginFill(0x000000, 1);
			_mask2.graphics.drawRect(0, 0, maskWidth, 400);
			_mask2.graphics.endFill();
			_mask2.opaqueBackground = true;
			
			_mask1.hitArea = new Sprite();
			_mask1.mouseEnabled = false;
			
			_mask2.hitArea = new Sprite();
			_mask2.mouseEnabled = false;
			
			_mask1.cacheAsBitmap = true;
			_mask1.cacheAsBitmapMatrix = m;
			
			_mask2.cacheAsBitmap = true;
			_mask2.cacheAsBitmapMatrix = m;
			
			//_mask.opaqueBackground = true;
			
			//imageContainer.mask = _mask;
			
			container.addChild(back);
			container.addChild(imageContainer);
			imageContainer.addChild(_mask1);
			imageContainer.addChild(_mask2);
			
			//_mask1.visible = false;
			_mask2.visible = false;
			
			//container.addChild(_antiMask);
			//container.addChild(_mask);
			
			container.x = 10;
			container.y = 10;
			
			//container.blendMode = BlendMode.LAYER;
			//_mask.blendMode = BlendMode.ALPHA;
			//_antiMask.blendMode = BlendMode.ERASE;
			//_antiMask.blendMode = BlendMode.SUBTRACT;
			//imageContainer.blendMode = BlendMode.NORMAL;
			//imageContainer.blendMode = BlendMode.LAYER;
			
			addChild(container);
			
			GestureTouchEmulator.emulate(container, this);
			GestureTouchEmulator.emulate(imageContainer, this);
			
			//imageContainer.addEventListener(TouchEvent.TOUCH_BEGIN, touchHandler);
			
			updateMask();
		}
		
		protected function limitContent (pPosition:Number):Number
		{
			return Math.max(back.width - (_images.length * _image1.width), Math.min(pPosition, 0));
		}
		
		protected var _leftMasked:DisplayObject;
		protected var _rightMasked:DisplayObject;
		
		protected function updateMask ():void
		{
			_mask1.x = -imageContainer.x;
			_mask2.x = -imageContainer.x;
			
			var leftIndex:int = Math.max(0, Math.floor( -imageContainer.x / _image1.width));
			var rightIndex:int = Math.min(_images.length, Math.floor((back.width - imageContainer.x) / _image1.width));
			
			var left:DisplayObject = _images[leftIndex];
			var right:DisplayObject = _images[rightIndex];
			
			var outLeft:DisplayObject = _images[leftIndex - 1];
			var outRight:DisplayObject = _images[rightIndex + 1];
			
			if (outLeft != null && outLeft.visible)
				outLeft.visible = false;
			
			if (outRight != null && outRight.visible)
				outRight.visible = false;
			
			if (left != _leftMasked && _leftMasked != null && _leftMasked.mask != null)
			{
				_leftMasked.mask = null;
				_leftMasked = null;
			}
			
			if (right != _rightMasked && _rightMasked != null && _rightMasked.mask != null)
			{
				_rightMasked.mask = null;
				_rightMasked = null;
			}
			
			if (left != null)
			{
				left.visible = true;
				
				left.mask = _mask1;
				_leftMasked = left;
				
			}
			if (right != null)
			{
				right.visible = true;
				
				right.mask = _mask2;
				_rightMasked = right;
			}
		}
		
		
		public function gestureTouchHandler (event:GestureTouchEvent):void 
		{
			//trace(event.type);
			
			var dragEvent:GestureTouchDragEvent
			
			if (event.currentTarget == imageContainer)
			{
				if (event is GestureTouchDragEvent)
				{
					dragEvent = (event as GestureTouchDragEvent);
					
					if (dragEvent.isHorizontal || dragEvent.isBoth)
					{
						if (event.type == GestureTouchDragEvent.LOCK_DRAG || event.type == GestureTouchDragEvent.START_DRAG)
						{
							TweenMax.killTweensOf(event.currentTarget);
						}
						else if (event.type == GestureTouchDragEvent.DRAGGING)
						{
							if ((event.currentTarget as Sprite).x != limitContent(imageContainer.x))
								dragEvent.xDelta /= 2;
							
							(event.currentTarget as Sprite).x += dragEvent.xDelta;
							
							updateMask();
						}
						else if (event.type == GestureTouchDragEvent.CANCEL_DRAG_RELEASE)
						{
							TweenMax.to(event.currentTarget, .5, {
								x: limitContent(imageContainer.x),
								ease: Strong.easeOut,
								onUpdate: updateMask
							});
						}
						else if (event.type == GestureTouchDragEvent.STOP_DRAG)
						{
							var limited:Number = limitContent(imageContainer.x);
							
							if (limited != imageContainer.x)
							{
								TweenMax.to(event.currentTarget, .5, {
									x: limitContent(imageContainer.x),
									ease: Strong.easeOut,
									onUpdate: updateMask
								});
							}
							else
							{
								var destination:Number = imageContainer.x + dragEvent.xDelta * 10;
								limited = limitContent(destination);
								
								TweenMax.to(event.currentTarget, limited != destination ? 1.1 : .8, {
									x: limited,
									ease: limited != destination ? Back.easeOut : Strong.easeOut,
									onUpdate: updateMask
								});
							}
						}
					}
				}
			}
			else if (event.currentTarget == container)
			{
				if (event is GestureTouchDragEvent && event.type == GestureTouchDragEvent.DRAGGING)
				{
					dragEvent = (event as GestureTouchDragEvent);
					
					if (dragEvent.isVertical)
					{
						(event.currentTarget as Sprite).y += dragEvent.yDelta;
					}
				}
			}
		}
		
		protected function touchHandler (e:TouchEvent):void 
		{
			trace(e.type, DisplayObject(e.target).name, e.target, e.currentTarget, e.bubbles, e.eventPhase, e.cancelable);
		}
	}
}